Instance Chains
論文
こういう構文
code:purs(hs)
instance showString :: MyShow String where
myShow s = s
else instance showBoolean :: MyShow Boolean where
myShow true = "true"
myShow false = "false"
instance宣言にelseが付いているmrsekut.icon
型クラスの引数が重複している場合に、どれを選択すれば良いかを明示することができる
型クラスの引数は複数取り得るがまずは1つについて見てみる
code:purs(hs)
class MyShow a where
myShow :: a -> String
instance showString :: MyShow String where
myShow s = s
else instance showBoolean :: MyShow Boolean where
myShow true = "true"
myShow false = "false"
else instance showA :: MyShow a where
myShow _ = "Invalid"
data MysteryItem = MysteryItem
ここではMyShowに対してのinstanceを複数個宣言している
instance chainがないと困るのは↓この定義があるせい
code:purs(hs)
instance showA :: MyShow a where
myShow _ = "Invalid"
任意の型aに対して、MyShowのinstanceを定義している
すると、MyShow Stringを考えたい場合にコンパイラは以下の2つの定義のどちらを採用すべきか自明でなくなる
code:purs(hs)
instance showString :: MyShow String where
myShow s = s
instance showA :: MyShow a where
myShow _ = "Invalid"
これは型エラーになる
MyShow Stringは、MyShow Stringでもあるし(当たり前)、MyShow aでもある
「上に書いたほうが優先順位が高い」というルールはない
そもそも別ファイルでも定義できるmrsekut.icon
そこでelse instanceを使うことで「上に書いたほうが優先順位が高い」として、これを明示することができる
myShow "hoge"の場合は、MyShow Stringの定義を採用し、
myShow 100の場合は、MyShow aの定義を採用することになる
code:purs(hs)
class IsEqual (l :: Type) (r :: Type) (b :: Boolean) | l r -> b
instance isEqualRefl :: IsEqual l l True
else instance isEqualDiff :: IsEqual l r False
3引数型クラスのinstanceについて、第1引数と第2引数が同じ型かどうかで定義を分けている
hsにもあるのだろうか?
これ?
参考
purs公式のdocs
説明がうすすぎると思う
3引数型クラスを例に取った説明
簡潔だがdocsよりは詳しい